Chapter 3 - Introduction to Scheme

2. Scheme

Scheme is a programming language that is a descendant of Lisp, one of the earliest programming languages. Lisp (which stands for List Processing) was specified in 1958.

Like Python, Scheme is also an imperative language. However, Scheme is based on expressions rather than statements.

For these notebooks, we will use Calysto Scheme.

2.1 Expressions

2.1.1 Literals

Literals are expressions that evaluate to themselves.


In [1]:
1


Out[1]:
1

In [17]:
2


Out[17]:
2

In [19]:
-3


Out[19]:
-3

In [2]:
3.14


Out[2]:
3.14

In [18]:
"apple"


Out[18]:
"apple"

So far, Scheme looks exactly like Python.


In [14]:
(quote apple)


Out[14]:
apple

In [4]:
'apple


Out[4]:
a

2.1.2 Symbols

Difference between variable and symbol.


In [9]:
+


Out[9]:
#<procedure>

2.1.3 Procedure Calls


In [15]:
(+ 1 2)


Out[15]:
3

In [16]:
(1 + 2)


Traceback (most recent call last):
  File "In [16]", line 1, col 1, in 'application'
  File "In [16]", line 1, col 1
RunTimeError: attempt to apply non-procedure '1'

Sidebar 2-1: How to Read Scheme Error Messages

Calysto error messages appear very similar to Python's error messages and are largely interpreted in the same manner. The best way to read them is to start at the bottom. In the above example, the specific error message is:

RunTimeError: attempt to apply non-procedure '1'

Above the error message is the "traceback" also called the "call stack". This is a representation of the sequence of procedure calls that lead to the error. If the procedure call originated from code from a file, the filename would be listed after the word "File" on each line. If the procedure call originated from a notebook cell, then the word "In" followed by the cell execution number in square brackets.

2.1.4 Lists

Scheme has very few built-in data structures.


In [7]:
(quote (1 2 3))


Out[7]:
(1 2 3)

In [8]:
'(1 2 3)


Out[8]:
(1 2 3)

In [12]:
'(1 + 1)


Out[12]:
(1 + 1)

Special Values


In [22]:
void


Out[22]:
#<procedure>

In [23]:
(void)

1.2 Equality

=

Unlike Python, Scheme has different equality operators depending on the type of objects to compare.

The = predicate is used on numbers.


In [5]:
(= 1 1)


Out[5]:
#t

In [4]:
(= 2 3)


Out[4]:
#f

In [7]:
(= 3.1415 3.1415)


Out[7]:
#f

The = predicate cannot be used on any other type of data:


In [3]:
(= '() '())


Traceback (most recent call last):
  File "In [3]", line 1, col 1, in '='
  File "In [3]", line 1, col 1
RunTimeError: attempt to apply = on non-numeric argument

eq?

The eq? predicate is used to see if two items refer to the same item in memory.

Like Python, lists of objects are different.


In [9]:
(eq? '(1) '(1))


Out[9]:
#f

Unlike Python, the empty list is a unique object:


In [8]:
(eq? '() '())


Out[8]:
#t

In [16]:
(eq? "a" "a")


Out[16]:
#t

The behavior of the eq? predicate on numbers and strings is dependent on the implementation of Scheme. In fact, in Calysto Scheme, it is dependent on the value of the type.

For example, the number 1 is the same place in memory:


In [18]:
(eq? 1 1)


Out[18]:
#t

However, for other values of numbers, it might not be the same place in memory:


In [1]:
(eq? 57663463467 57663463467)


Out[1]:
#f

eqv?

Because eq? can give different values for numbers and strings depending on the implementation, it is generally not useful. Rather, you should use the eqv? predicate. It does what you expect: for non-numbers and non-strings it checks memory, but it gives #t if the two values of strings and numbers are the same.


In [2]:
(eqv? 57663463467 57663463467)


Out[2]:
#t

In [3]:
(eqv? 1.1 1.1)


Out[3]:
#t

In [4]:
(eqv? "a" "a")


Out[4]:
#t

In [25]:
(number? 57663463467)


Out[25]:
#t

In [28]:
(typeof 57663463467)


Out[28]:
<class 'int'>

In [7]:
(quote "hello")


Out[7]:
"hello"

In [10]:
(eq? 'a 'a)


Out[10]:
#t

In [2]:
(+ (complex 2 5) 1)


Out[2]:
(3+5j)

In [ ]: